package org.jeecg.modules.demo.upload.service.impl;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.MinioUtil;
import org.jeecg.common.util.oss.GetContentType;
import org.jeecg.modules.demo.upload.entity.OOS;
import org.jeecg.modules.demo.upload.entity.ZyUpload;
import org.jeecg.modules.demo.upload.mapper.ZyUploadMapper;
import org.jeecg.modules.demo.upload.service.ZyUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @program: git-zhihui-backen
 * @description:
 * @author: 张浩
 * @create: 2023-06-18 17:24
 **/
@Service
@Slf4j
public class ZyUploadServiceImpl extends ServiceImpl<ZyUploadMapper, ZyUpload> implements ZyUploadService {


//    ApplicationHome applicationHome = new ApplicationHome(this.getClass());
//    String Path =applicationHome.getDir().getParentFile()
//           .getParentFile().getAbsolutePath()+"\\src\\main\\resources";
    String Path=System.getProperty("user.home") + "/Downloads";

//     String Path = "C:\\Users\\86187\\Desktop\\3.6.0\\smart-site-Front-end\\jeecgboot-vue3\\public";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    @Autowired
    private ZyUploadMapper zyUploadMapper;
    @Autowired
    private  GetContentType getContentType;
    @Override
    public Result<String> add(MultipartFile file) {
        try {
            OSS ossClient = new OSSClientBuilder().build(OOS.ALIYUN_OSS_ENDPOINT, OOS.ALIYUN_OSS_ACCESSKEYID, OOS.ALIYUN_OSS_ACCESSKEYSECRET);
            String url="";
            //得到初始文件名originalFileName
            String filename=file.getOriginalFilename();
           // 指定该路径下，对应的文件
            File file1 =new File(Path,filename);
            file.transferTo(file1);
            log.info(file1.getAbsolutePath());
            Integer size= Math.toIntExact((file.getSize()));
            // oss中的文件夹名
            String objectName = sdf.format(new Date()) + "/" + filename;
            String type=getContentType.getContentType(filename.substring(filename.lastIndexOf(".")));
            // 创建上传文件的元信息，可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType(type);
            objectMetadata.setContentDisposition("inline");
            //缓存文件上传至OSS
            InputStream inputStream = new FileInputStream(file1);
            ossClient.putObject(OOS.ALIYUN_OSS_BUCKETNAME, objectName, inputStream, objectMetadata);

            log.info("*******运行到上传文件");// 设置URL过期时间为1小时。
            Date expiration = new Date(System.currentTimeMillis() + 360000 *3600 * 1000*24*2000*1000);
            // 设置样式，样式中包含文档预览参数。
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(OOS.ALIYUN_OSS_BUCKETNAME, objectName, HttpMethod.GET);
            req.setExpiration(expiration);
            URL signedUrl = ossClient.generatePresignedUrl(req);
            url=signedUrl.toString();
            String downloadUrl = url.toString() + "&download=" + URLEncoder.encode(objectName, "UTF-8");
            log.info(downloadUrl);
            Timestamp timestamp=new Timestamp(System.currentTimeMillis());
            /*
             * 设计存储到数据库的名字fileName
             * System.currentTimeMillis()获取文件存储到库时的时间
             * 获取时间加上文件名
             */
            ossClient.shutdown();

//            file1.delete();
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            System.out.println("loginUser = " + loginUser);
            String form=filename.substring(filename.lastIndexOf("."));
            ZyUpload zyUpload=new ZyUpload(url,filename,(size/1024.0),loginUser.getUsername(),timestamp,filename,"v1.0",null,url,type,loginUser.getUsername(),null,null,form);
            zyUploadMapper.insert(zyUpload);
           return Result.OK(url);
         } catch (Exception e) {
            e.printStackTrace();
            return Result.error("上传失败，运行错误");
        }
    }

    @Override
    public Result<Map<String,String>> add(MultipartFile file, String name) {
        Result<Map<String,String>> result = new Result<Map<String,String>>();
        Map<String,String> map = new HashMap(5);
        try {
            OSS ossClient = new OSSClientBuilder().build(OOS.ALIYUN_OSS_ENDPOINT, OOS.ALIYUN_OSS_ACCESSKEYID, OOS.ALIYUN_OSS_ACCESSKEYSECRET);
            String url="";
            //得到初始文件名originalFileName
            String filename=file.getOriginalFilename();
            //创建文件夹到目录下
            String path = Path  + "/" + name;
            File folder = new File(path);
            if (!folder.isDirectory()){
                folder.mkdir();
            }
            File file1 =new File(path,filename);
            file.transferTo(file1);
            log.info("bim文件的存放路径 {}",file1.getAbsolutePath());
            Integer size= Math.toIntExact((file.getSize()));
            // oss中的文件夹名
            String objectName = sdf.format(new Date()) + "/" + filename;
            String type=getContentType.getContentType(filename.substring(filename.lastIndexOf(".")));
            // 创建上传文件的元信息，可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType(type);
            objectMetadata.setContentDisposition("inline");
            //缓存文件上传至OSS
            InputStream inputStream = new FileInputStream(file1);
            ossClient.putObject(OOS.ALIYUN_OSS_BUCKETNAME, objectName, inputStream, objectMetadata);

            log.info("*******运行到上传文件");// 设置URL过期时间为1小时。
            Date expiration = new Date(System.currentTimeMillis() + 360000 *3600 * 1000*24*2000*1000);
            // 设置样式，样式中包含文档预览参数。
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(OOS.ALIYUN_OSS_BUCKETNAME, objectName, HttpMethod.GET);
            req.setExpiration(expiration);
            URL signedUrl = ossClient.generatePresignedUrl(req);
            url=signedUrl.toString();
            String downloadUrl = url.toString() + "&download=" + URLEncoder.encode(objectName, "UTF-8");
            log.info(downloadUrl);
            Timestamp timestamp=new Timestamp(System.currentTimeMillis());
            /*
             * 设计存储到数据库的名字fileName
             * System.currentTimeMillis()获取文件存储到库时的时间
             * 获取时间加上文件名
             */
            ossClient.shutdown();

            map.put("url",url);
            map.put("folder",path);
            return Result.OK(map);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("上传失败，运行错误");
        }
    }

    @Override
    public Result<String> addFile(MultipartFile file) {
        try {
            OSS ossClient = new OSSClientBuilder().build(OOS.ALIYUN_OSS_ENDPOINT, OOS.ALIYUN_OSS_ACCESSKEYID, OOS.ALIYUN_OSS_ACCESSKEYSECRET);
            String url="";
            //得到初始文件名originalFileName
            String filename=file.getOriginalFilename();
            File file1 =new File(Path,filename);
            file.transferTo(file1);
            log.info(file1.getAbsolutePath());
            Integer size= Math.toIntExact((file.getSize()));
            // oss中的文件夹名
            String objectName = sdf.format(new Date()) + "/" + filename;
            String type=getContentType.getContentType(filename.substring(filename.lastIndexOf(".")));
            // 创建上传文件的元信息，可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentType(type);
            objectMetadata.setContentDisposition("inline");
            //缓存文件上传至OSS
            InputStream inputStream = new FileInputStream(file1);
            ossClient.putObject(OOS.ALIYUN_OSS_BUCKETNAME, objectName, inputStream, objectMetadata);

            log.info("*******运行到上传文件");// 设置URL过期时间为1小时。
            Date expiration = new Date(System.currentTimeMillis() + 360000 *3600 * 1000*24*2000*1000);
            // 设置样式，样式中包含文档预览参数。
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(OOS.ALIYUN_OSS_BUCKETNAME, objectName, HttpMethod.GET);
            req.setExpiration(expiration);
            URL signedUrl = ossClient.generatePresignedUrl(req);
            url=signedUrl.toString();
            String downloadUrl = url.toString() + "&download=" + URLEncoder.encode(objectName, "UTF-8");
            log.info(downloadUrl);
            Timestamp timestamp=new Timestamp(System.currentTimeMillis());
            /*
             * 设计存储到数据库的名字fileName
             * System.currentTimeMillis()获取文件存储到库时的时间
             * 获取时间加上文件名
             */
            ossClient.shutdown();

            file1.delete();
//            ZyUpload zyUpload=new ZyUpload(url,filename,size,"admin",timestamp,filename,"v1.0,",null,url,type,"admin",null,null);
//            zyUploadMapper.insert(zyUpload);
            return Result.OK(url);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("上传失败，运行错误");
        }
    }

    @Override
    public Result<List<String>> listFolder() {
        List<String> folderName = new ArrayList<>();
        File folder = new File(Path);
        File[] subFolders = folder.listFiles(File::isDirectory);
        for (File subFolder : subFolders) {
            System.out.println(subFolder.getName());
            String name = subFolder.getName();
            folderName.add(name);
        }
        return Result.ok(folderName);
    }

    @Override
    public String uploadSceneFile(MultipartFile file) throws Exception {
        LocalDateTime date = LocalDateTime.now();
        String filename=file.getOriginalFilename();
        Integer size= Math.toIntExact((file.getSize()));
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println("sysUser = " + loginUser);
        Timestamp timestamp=new Timestamp(System.currentTimeMillis());
        String form=filename.substring(filename.lastIndexOf("."));
        //TODO minio
        //        String upload = OssBootUtil.upload1(file,filename.substring(filename.lastIndexOf(".")));
        String upload= MinioUtil.upload(file,null);
        log.info("图片上传完成" + upload);

//        ZyUpload zyUpload = new ZyUpload();
//        zyUpload.setAddress(upload);
//        zyUpload.setName(filename);
//        zyUpload.setSize(size/1024.0);
//        if (loginUser != null){
//            zyUpload.setPerson(loginUser.getRealname());
//        }
//        zyUpload.setUpdateTime(timestamp);
//        zyUpload.setPreview(upload);
//        zyUpload.setDownload(upload);
//        zyUpload.setForm(form);
//        zyUploadMapper.insert(zyUpload);
        return upload;
    }
    public String uploadSceneFile1(MultipartFile file) throws Exception {
        String filename=file.getOriginalFilename();
        //TODO minio
        //        String upload = OssBootUtil.upload1(file,filename.substring(filename.lastIndexOf(".")));
        String upload= MinioUtil.upload(file,null);

        log.info("图片上传完成" + upload);

        return upload;
    }
    public static void isDirectory(File file) {
        if(file.exists()){
            if (file.isFile()) {
                System.out.println("file is ==>>" + file.getAbsolutePath());
//                String name = file.getName();
            }else{
                File[] list = file.listFiles();
                System.out.println("list = " + list);
                if (list.length == 0) {
                    System.out.println(file.getAbsolutePath() + " is null");
                } else {
                    for (int i = 0; i < list.length; i++) {
                        isDirectory(list[i]);//递归调用
                    }
                }
            }
        }else{
            System.out.println("文件不存在！");
        }
    }

}
